home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
- * Copying of this file is granted according to the provisions
- * specified in the file COPYING which must accompany this file.
- */
-
-
- /*
- * dvi.c
- */
-
- #include "tex.h"
- #include "texext.h"
- #include "heap.h"
- #include "str.h"
- #include "io.h"
- #include "eq.h"
- #include "box.h"
- #include "scan.h"
- #include "tfm.h"
- #include "file.h"
- #include "pack.h"
- #include "print.h"
- #include "error.h"
- #include "dvi.h"
-
- byte_file dvi_file;
-
- ptr dvi_ptr;
- byte dvi_buf[DVI_BUF_SIZE];
- ptr dvi_limit = DVI_BUF_SIZE;
- val dvi_offset;
- val dvi_gone;
-
- qword c;
- qword f;
- ptr g;
- val lq;
- val lr;
- int cur_s = -1;/*DIFF*/
- scal cur_h;
- scal cur_v;
- fnt dvi_f;
- scal dvi_h;
- scal dvi_v;
- scal max_h;
- scal max_v;
- scal rule_dp;
- scal rule_ht;
- scal rule_wd;
- int max_push;
- int total_pages;
- int dead_cycles;
- bool doing_leaders;
- val last_bop = -1;
-
- ptr down_ptr;
- ptr right_ptr;
-
- dvi_swap ()
- {
- if (dvi_limit == DVI_BUF_SIZE) {
- write_dvi(0, HALF_BUF);
- dvi_limit = HALF_BUF;
- dvi_offset += DVI_BUF_SIZE;
- dvi_ptr = 0;
- } else {
- write_dvi(HALF_BUF, DVI_BUF_SIZE);
- dvi_limit = DVI_BUF_SIZE;
- }
- dvi_gone += HALF_BUF;
- }
-
- dvi_four (x)
- val x;
- {
- if (x >= 0) {
- dvi_out(x / 0100000000);
- } else {
- x += 010000000000;
- x += 010000000000;
- dvi_out(x / 0100000000 + 128);
- }
- x %= 01000000000;
- dvi_out(x / 0200000);
- x %= 0200000;
- dvi_out(x / 0400);
- dvi_out(x % 0400);
- }
-
- dvi_pop (l)
- val l;
- {
- if (l == dvi_offset + dvi_ptr && dvi_ptr > 0)
- decr(dvi_ptr);
- else dvi_out(POP);
- }
-
- dvi_font_def (f)
- fnt f;
- {
- int k;
-
- dvi_out(FNT_DEF1);
- dvi_out(f - FONT_BASE - 1);
- dvi_out(qo(font_check[f].b0));
- dvi_out(qo(font_check[f].b1));
- dvi_out(qo(font_check[f].b2));
- dvi_out(qo(font_check[f].b3));
- dvi_four(font_size[f]);
- dvi_four(font_dsize[f]);
- dvi_out(length(font_area[f]));
- dvi_out(length(font_name[f]));
- for (k = str_start[font_area[f]]; k < str_start[font_area[f] + 1]; incr(k))
- dvi_out(str_pool[k]);
- for (k = str_start[font_name[f]]; k < str_start[font_name[f] + 1]; incr(k))
- dvi_out(str_pool[k]);
- }
-
- #define Y_HERE 1
- #define Z_HERE 2
- #define YZ_OK 3
- #define Y_OK 4
- #define Z_OK 5
- #define D_FIXED 6
- #define NONE_SEEN 0
- #define Y_SEEN 6
- #define Z_SEEN 12
-
- movement (w, o)
- scal w;
- byte o;
- {
- val k;
- ptr p;
- ptr q;
- int mstate;
-
- q = get_node(MOVEMENT_NODE_SIZE);
- width(q) = w;
- location(q) = dvi_offset + dvi_ptr;
- if (o == DOWN1) {
- link(q) = down_ptr;
- down_ptr = q;
- } else {
- link(q) = right_ptr;
- right_ptr = q;
- }
- mstate = NONE_SEEN;
- for (p = link(q); p != NULL; p = link(p)) {
- if (width(p) == w) {
- switch (mstate + info(p))
- {
- case NONE_SEEN + YZ_OK:
- case NONE_SEEN + Y_OK:
- case Z_SEEN + YZ_OK:
- case Z_SEEN + Y_OK:
- if (location(p) < dvi_gone)
- goto not_found;
- else {
- k = location(p) - dvi_offset;
- if (k < 0)
- k += DVI_BUF_SIZE;
- dvi_buf[(int)k] += Y1 - DOWN1;
- info(p) = Y_HERE;
- goto found;
- }
- break;
-
- case NONE_SEEN + Z_OK:
- case Y_SEEN + YZ_OK:
- case Y_SEEN + Z_OK:
- if (location(p) < dvi_gone) {
- goto not_found;
- } else {
- k = location(p) - dvi_offset;
- if (k < 0)
- k += DVI_BUF_SIZE;
- dvi_buf[(int)k] += Z1 - DOWN1;
- info(p) = Z_HERE;
- goto found;
- }
- break;
-
- case NONE_SEEN + Y_HERE:
- case NONE_SEEN + Z_HERE:
- case Y_SEEN + Z_HERE:
- case Z_SEEN + Y_HERE:
- goto found;
- break;
- }
- } else {
- switch (mstate + info(p))
- {
- case NONE_SEEN + Y_HERE:
- mstate = Y_SEEN;
- break;
-
- case NONE_SEEN + Z_HERE:
- mstate = Z_SEEN;
- break;
-
- case Y_SEEN + Z_HERE:
- case Z_SEEN + Y_HERE:
- goto not_found;
- break;
-
- default:
- break;
- }
- }
- }
-
- not_found:
- info(q) = YZ_OK;
- if (abs(w) >= 040000000) {
- dvi_out(o + 3);
- dvi_four(w);
- return;
- }
- if (abs(w) >= 0100000) {
- dvi_out(o + 2);
- if (w < 0)
- w += 0100000000;
- dvi_out(w / 0200000);
- w %= 0200000;
- goto two;
- }
- if (abs(w) >= 0200) {
- dvi_out(o + 1);
- if (w < 0)
- w += 0200000;
- goto two;
- }
- dvi_out(o);
- if (w < 0)
- w += 0400;
- goto one;
-
- two: dvi_out(w / 0400);
- one: dvi_out(w % 0400);
- return;
-
- found:
- info(q) = info(p);
- if (info(q) == Y_HERE) {
- dvi_out(o + Y0 - DOWN1);
- while (link(q) != p) {
- q = link(q);
- switch (info(q))
- {
- case YZ_OK:
- info(q) = Z_OK;
- break;
-
- case Y_OK:
- info(q) = D_FIXED;
- break;
- }
- }
- } else {
- dvi_out(o + Z0 - DOWN1);
- while (link(q) != p) {
- q = link(q);
- switch (info(q))
- {
- case YZ_OK:
- info(q) = Y_OK;
- break;
-
- case Z_OK:
- info(q) = D_FIXED;
- break;
- default:
- break;
- }
- }
- }
- }
-
- prune_movements (l)
- val l;
- {
- ptr p;
-
- while (down_ptr != NULL) {
- if (location(down_ptr) < l)
- break;
- p = down_ptr;
- down_ptr = link(p);
- free_node(p, MOVEMENT_NODE_SIZE);
- }
- while (right_ptr != NULL) {
- if (location(right_ptr) < l)
- break;
- p = right_ptr;
- right_ptr = link(p);
- free_node(p, MOVEMENT_NODE_SIZE);
- }
- }
-
- hlist_out ()
- {
- ptr p;
- scal lx;
- scal edge;
- int g_sign;
- scal save_h;
- scal save_v;
- gord g_order;
- val save_loc;
- ptr this_box;
- scal base_line;
- scal leader_wd;
- scal left_edge;
- ptr leader_box;
- bool outer_doing_leaders;
-
- this_box = temp_ptr;
- g_order = glue_order(this_box);
- g_sign = glue_sign(this_box);
- p = list_ptr(this_box);
- incr(cur_s);
- if (cur_s > 0)
- dvi_out(PUSH);
- if (cur_s > max_push)
- max_push = cur_s;
- save_loc = dvi_offset + dvi_ptr;
- base_line = cur_v;
- left_edge = cur_h;
- while (p != NULL) {
- reswitch:
- if (is_char_node(p)) {
- synch_h();
- synch_v();
- do {
- f = font(p);
- c = character(p);
- if (f != dvi_f) {
- if (!font_used[f]) {
- dvi_font_def(f);
- font_used[f] = TRUE;
- }
- if (f <= 64 + FONT_BASE) {
- dvi_out(f - FONT_BASE - 1 + FNT_NUM_0);
- } else {
- dvi_out(FNT1);
- dvi_out(f - FONT_BASE - 1);
- }
- dvi_f = f;
- }
- if (c >= qi(128))/*DIFF*/
- dvi_out(SET1);/*DIFF*/
- dvi_out(qo(c));/*DIFF*/
- cur_h += char_width(f, char_info(f, c));
- p = link(p);
- } while (is_char_node(p));
- dvi_h = cur_h;
- } else {
- switch (type(p))
- {
- case HLIST_NODE:
- case VLIST_NODE:
- if (list_ptr(p) == NULL)
- cur_h += width(p);
- else {
- save_h = dvi_h;
- save_v = dvi_v;
- cur_v = base_line + shift_amount(p);
- temp_ptr = p;
- edge = cur_h;
- if (type(p) == VLIST_NODE)
- vlist_out();
- else hlist_out();
- dvi_h = save_h;
- dvi_v = save_v;
- cur_h = edge + width(p);
- cur_v = base_line;
- }
- break;
-
- case RULE_NODE:
- rule_ht = height(p);
- rule_dp = depth(p);
- rule_wd = width(p);
- goto fin_rule;
- break;
-
- case WHATSIT_NODE:
- out_whatsit(p);
- break;
-
- case GLUE_NODE:
- g = glue_ptr(p);
- rule_wd = width(g);
- if (g_sign != NORMAL) {
- if (g_sign == STRETCHING) {
- if (stretch_order(g) == g_order)
- rule_wd += round(glue_set(this_box) * stretch(g));
- } else {
- if (shrink_order(g) == g_order)
- rule_wd -= round(glue_set(this_box) * shrink(g));
- }
- }
- if (subtype(p) >= A_LEADERS) {
- leader_box = leader_ptr(p);
- if (type(leader_box) == RULE_NODE) {
- rule_ht = height(leader_box);
- rule_dp = depth(leader_box);
- goto fin_rule;
- }
- leader_wd = width(leader_box);
- if (leader_wd > 0 && rule_wd > 0) {
- rule_wd += 10;/*DIFF*/
- edge = cur_h + rule_wd;
- lx = 0;
- if (subtype(p) == A_LEADERS) {
- save_h = cur_h;
- cur_h = left_edge +
- leader_wd * ((cur_h - left_edge) / leader_wd);
- if (cur_h < save_h)
- cur_h += leader_wd;
- } else {
- lq = rule_wd / leader_wd;
- lr = rule_wd % leader_wd;
- if (subtype(p) == C_LEADERS)
- cur_h += (lr / 2);
- else {
- lx = (2 * lr + lq + 1) / (2 * lq + 2);
- cur_h += (lr - (lq - 1) * lx) / 2;
- }
- }
- while (cur_h + leader_wd <= edge) {
- cur_v = base_line + shift_amount(leader_box);
- synch_v();
- save_v = dvi_v;
- synch_h();
- save_h = dvi_h;
- temp_ptr = leader_box;
- outer_doing_leaders = doing_leaders;
- doing_leaders = TRUE;
- if (type(leader_box) == VLIST_NODE)
- vlist_out();
- else hlist_out();
- doing_leaders = outer_doing_leaders;
- dvi_v = save_v;
- dvi_h = save_h;
- cur_v = save_v;
- cur_h = save_h + lx + leader_wd;
- }
- }
- cur_h = edge - 10;/*DIFF*/
- goto next_p;
- }
- goto move_past;
- break;
-
- case KERN_NODE:
- case MATH_NODE:
- cur_h += width(p);
- break;
-
- case LIGATURE_NODE:
- make_char_from_lig();
- goto reswitch;
-
- default: break;
- }
- goto next_p;
-
- fin_rule:
- if (is_running(rule_ht))
- rule_ht = height(this_box);
- if (is_running(rule_dp))
- rule_dp = depth(this_box);
- rule_ht = rule_ht + rule_dp;
- if (rule_ht > 0 && rule_wd > 0) {
- synch_h();
- cur_v = base_line + rule_dp;
- synch_v();
- dvi_out(SET_RULE);
- dvi_four(rule_ht);
- dvi_four(rule_wd);
- cur_v = base_line;
- dvi_h += rule_wd;
- }
-
- move_past:
- cur_h += rule_wd;
-
- next_p:
- p = link(p);
- }
- }
- prune_movements(save_loc);
- if (cur_s > 0)
- dvi_pop(save_loc);
- decr(cur_s);
- }
-
- vlist_out ()
- {
- ptr p;
- scal lx;
- scal edge;
- int g_sign;
- scal save_h;
- scal save_v;
- gord g_order;
- val save_loc;
- scal top_edge;
- ptr this_box;
- scal leader_ht;
- scal left_edge;
- ptr leader_box;
- bool outer_doing_leaders;
-
- this_box = temp_ptr;
- g_order = glue_order(this_box);
- g_sign = glue_sign(this_box);
- p = list_ptr(this_box);
- incr(cur_s);
- if (cur_s > 0)
- dvi_out(PUSH);
- if (cur_s > max_push)
- max_push = cur_s;
- save_loc = dvi_offset + dvi_ptr;
- left_edge = cur_h;
- cur_v -= height(this_box);
- top_edge = cur_v;
- while (p != NULL) {
- if (is_char_node(p))
- confusion("vlistout");
- else {
- switch (type(p))
- {
- case HLIST_NODE:
- case VLIST_NODE:
- if (list_ptr(p) == NULL)
- cur_v += height(p) + depth(p);
- else {
- cur_v += height(p);
- synch_v();
- save_h = dvi_h;
- save_v = dvi_v;
- cur_h = left_edge + shift_amount(p);
- temp_ptr = p;
- if (type(p) == VLIST_NODE)
- vlist_out();
- else hlist_out();
- dvi_h = save_h;
- dvi_v = save_v;
- cur_v = save_v + depth(p);
- cur_h = left_edge;
- }
- break;
-
- case RULE_NODE:
- rule_ht = height(p);
- rule_dp = depth(p);
- rule_wd = width(p);
- goto fin_rule;
- break;
-
- case WHATSIT_NODE:
- out_whatsit(p);
- break;
-
- case GLUE_NODE:
- g = glue_ptr(p);
- rule_ht = width(g);
- if (g_sign != NORMAL) {
- if (g_sign == STRETCHING) {
- if (stretch_order(g) == g_order)
- rule_ht += round(glue_set(this_box) * stretch(g));
- } else if (shrink_order(g) == g_order)
- rule_ht -= round(glue_set(this_box) * shrink(g));
- }
- if (subtype(p) >= A_LEADERS) {
- leader_box = leader_ptr(p);
- if (type(leader_box) == RULE_NODE) {
- rule_wd = width(leader_box);
- rule_dp = 0;
- goto fin_rule;
- }
- leader_ht = height(leader_box) + depth(leader_box);
- if (leader_ht > 0 && rule_ht > 0) {
- rule_ht += 10;/*DIFF*/
- edge = cur_v + rule_ht;
- lx = 0;
- if (subtype(p) == A_LEADERS) {
- save_v = cur_v;
- cur_v = top_edge +
- leader_ht * ((cur_v - top_edge) / leader_ht);
- if (cur_v < save_v)
- cur_v += leader_ht;
- } else {
- lq = rule_ht / leader_ht;
- lr = rule_ht % leader_ht;
- if (subtype(p) == C_LEADERS)
- cur_v += lr / 2;
- else {
- lx = (2 * lr + lq + 1) / (2 * lq + 2);
- cur_v += (lr - (lq - 1) * lx) / 2;
- }
- }
- while (cur_v + leader_ht <= edge) {
- cur_h = left_edge + shift_amount(leader_box);
- synch_h();
- save_h = dvi_h;
- cur_v += height(leader_box);
- synch_v();
- save_v = dvi_v;
- temp_ptr = leader_box;
- outer_doing_leaders = doing_leaders;
- doing_leaders = TRUE;
- if (type(leader_box) == VLIST_NODE)
- vlist_out();
- else hlist_out();
- doing_leaders = outer_doing_leaders;
- dvi_v = save_v;
- dvi_h = save_h;
- cur_h = save_h;
- cur_v = save_v - height(leader_box)+lx+leader_ht;
- }
- cur_v = edge - 10;/*DIFF*/
- goto next_p;
- }
- }
- goto move_past;
- break;
-
- case KERN_NODE:
- cur_v += width(p);
- break;
-
- default:
- break;
- }
- goto next_p;
-
- fin_rule:
- if (is_running(rule_wd))
- rule_wd = width(this_box);
- rule_ht += rule_dp;
- cur_v += rule_ht;
- if (rule_ht > 0 && rule_wd > 0) {
- synch_h();
- synch_v();
- dvi_out(PUT_RULE);
- dvi_four(rule_ht);
- dvi_four(rule_wd);
- }
- goto next_p;
-
- move_past:
- cur_v += rule_ht;
- }
-
- next_p:
- p = link(p);
- }
- prune_movements(save_loc);
- if (cur_s > 0)
- dvi_pop(save_loc);
- decr(cur_s);
- }
-
- #define ensure_dvi_open() \
- {if (dvi_name == 0) { \
- if (job_name == 0) \
- job_name = str_texput; \
- pack_job_name(str_dvi); \
- while ((dvi_file = b_open_out()) == NULL) \
- prompt_file_name("file name for output", str_dvi); \
- dvi_name = b_make_name_string(dvi_file);}}
-
- ship_out (p)
- ptr p;
- {
- int j;
- int k;
- int s;
- val page_loc;
-
- if (tracing_output > 0) {
- print_ln();
- print_nl("Completed box being shipped out");
- }
- if (term_offset > MAX_PRINT_LINE - 9)
- print_ln();
- else if (term_offset > 0 || file_offset > 0)
- print_char(' ');
- print_char('[');
- for (j = 9; count(j) == 0 && j > 0; decr(j))
- {}
- for (k = 0; k <= j; incr(k)) {
- print_val(count(k));
- if (k < j)
- print_char('.');
- }
- update_terminal();
- if (tracing_output > 0) {
- print_char(']');
- begin_diagnostic();
- show_box(p);
- end_diagnostic(TRUE);
- }
- if (height(p) > MAX_DIMEN || depth(p) > MAX_DIMEN ||
- height(p) + depth(p) + v_offset > MAX_DIMEN ||
- width(p) + h_offset > MAX_DIMEN) {
- print_err("Huge page cannot be shipped out");
- help_huge_page();
- error();
- if (tracing_output <= 0) {
- begin_diagnostic();
- print_nl("The following box has been deleted:");
- show_box(p);
- end_diagnostic(TRUE);
- }
- goto done;
- }
- if (height(p) + depth(p) + v_offset > max_v)
- max_v = height(p) + depth(p) + v_offset;
- if (width(p) + h_offset > max_h)
- max_h = width(p) + h_offset;
- dvi_h = 0;
- dvi_v = 0;
- cur_h = h_offset;
- dvi_f = NULL_FONT;
- /*DIFF cur_s = -1;*/
- ensure_dvi_open();
- if (total_pages == 0) {
- dvi_out(PRE);
- dvi_out(ID_BYTE);
- dvi_four(25400000);
- dvi_four(473628672);
- prepare_mag();
- dvi_four(mag);
- old_setting = selector;
- selector = NEW_STRING;
- print("Common TeX output ");
- print_int(year);
- print_char('.');
- print_two(month);
- print_char('.');
- print_two(day);
- print_char(':');
- print_two(time / 60);
- print_two(time % 60);
- selector = old_setting;
- dvi_out(cur_length());
- for (s = str_start[str_ptr]; s < pool_ptr; incr(s))
- dvi_out(str_pool[s]);
- pool_ptr = str_start[str_ptr];
- }
- page_loc = dvi_offset + dvi_ptr;
- dvi_out(BOP);
- for (k = 0; k <= 9; incr(k))
- dvi_four(count(k));
- dvi_four(last_bop);
- last_bop = page_loc;
- cur_v = height(p) + v_offset;
- temp_ptr = p;
- if (type(p) == VLIST_NODE)
- vlist_out();
- else hlist_out();
- dvi_out(EOP);
- incr(total_pages);
- cur_s = -1;
-
- done:
- if (tracing_output <= 0) print_char(']');
- dead_cycles = 0;
- update_terminal();
-
- #ifdef STAT
- if (tracing_stats > 1) {
- print_nl("Memory usage before: ");
- print_int(var_used);
- print_char('&');
- print_int(dyn_used);
- print_char(';');
- }
- #endif
-
- flush_node_list(p);
-
- #ifdef STAT
- if (tracing_stats > 1) {
- print(" after: ");
- print_int(var_used);
- print_char('&');
- print_int(dyn_used);
- print("; still untouched: ");
- print_int(hi_mem_min - lo_mem_max - 1);
- print_ln();
- }
- #endif
- }
-
- /*
- * Help text
- */
-
- help_huge_page ()
- {
- help2("The page just created is more than 18 feet tall or",
- "more than 18 feet wide, so I suspect something went wrong.");
- }
-